<template>
	<view class="container">
		<canvas style="position: absolute;
    right: -750px;" v-show="elBgIdShowOne" canvas-id="gaugeCanvas" class="gauge-canvas" @error="handleError"></canvas>
		<image class="gauge-canvas" v-show="elBgIdShowTwo" :src="elBgIdUrl" />
		<view class="center-area-box">
			<view class="center-area" :style="{ transform: `rotate(${pointerAngle}deg)` }"></view>
			<text class="center-text">{{ currentSection ? currentSection.label : '' }}</text>
		</view>
	</view>
</template>
<script>
	export default {
		props: {
			sections: {
				type: Array,
				default: () => [{
						color: '#5B9BD5',
						label: '程度一',
						description: '这是程度一的描述',
						range: 40
					},
					{
						color: '#46BFBD',
						label: '程度二',
						description: '这是程度二的描述',
						range: 60
					},
				]
			},
			maxScore: {
				type: Number,
				default: 100
			},
			score: {
				type: [String, Number],
				default: 50,
			}
		},
		data() {
			return {
				ctx: null,
				centerX: 150,
				centerY: 150,
				radius: 90,
				currentScore: 0,
				currentSection: null,
				elBgIdStart: true,
				elBgIdShowOne: true,
				elBgIdShowTwo: false,
				elBgIdUrl: ''
			}
		},
		computed: {
			pointerAngle() {
				const startAngle = Math.PI * 0.8;
				const endAngle = Math.PI * 2.2;
				const totalAngle = (endAngle - startAngle) * (180 / Math.PI);
				const anglePerScore = totalAngle / this.maxScore;
				return (startAngle * (180 / Math.PI)) + (this.currentScore * anglePerScore) - 180;
			}
		},
		mounted() {
			this.initCanvas()
		},
		methods: {
			initCanvas() {
				this.ctx = uni.createCanvasContext('gaugeCanvas', this)
				this.updateScore(Number(this.score))
			},
			drawGauge() {
				const ctx = this.ctx;
				const centerX = this.centerX;
				const centerY = this.centerY;
				const radius = this.radius;
				const startAngle = Math.PI * 0.8;
				const endAngle = Math.PI * 2.2;
				const totalAngle = endAngle - startAngle;
				const gapAngle = Math.PI * 0.01;
				const numberOfSections = this.sections.length;
				const totalGapAngle = (numberOfSections - 1) * gapAngle;
				const availableAngle = totalAngle - totalGapAngle;
				let currentScoreSum = 0;
				this.sections.forEach((section, index) => {
					const adjustedRange = section.range * (availableAngle / totalAngle);
					const sectionStart = startAngle + (currentScoreSum / this.maxScore) * availableAngle + (index *
						gapAngle);
					const sectionEnd = startAngle + ((currentScoreSum + adjustedRange) / this.maxScore) *
						availableAngle + (index * gapAngle);
					ctx.beginPath();
					ctx.arc(centerX, centerY, radius, sectionStart, sectionEnd, false);
					ctx.lineWidth = 20;
					ctx.strokeStyle = '#E3E3E3';
					ctx.stroke();
					if (index < this.sections.length - 1) {
						currentScoreSum += adjustedRange + (gapAngle / availableAngle) * this.maxScore;
					} else {
						currentScoreSum += adjustedRange;
					}
					const sectionCenterAngle = (sectionStart + sectionEnd) / 2;
					const labelRadius = radius + 30;
					const labelX = centerX + labelRadius * Math.cos(sectionCenterAngle);
					const labelY = centerY + labelRadius * Math.sin(sectionCenterAngle);
					ctx.setFontSize(16);
					ctx.setFillStyle('rgba(0,0,0,0.5)');
					ctx.setTextAlign('center');
					ctx.setTextBaseline('top');
					ctx.fillText(section.label, labelX, labelY - 10);
				});
				currentScoreSum = 0;
				const scoreAngle = startAngle + (totalAngle * this.currentScore / this.maxScore);
				const drawTick = (section, sectionStart, sectionEnd) => {
					const tickCount = Math.floor(section.range);
					const tickAngle = (sectionEnd - sectionStart) / (tickCount || 1);
					for (let j = 0; j <= tickCount; j++) {
						const tickStart = sectionStart + j * tickAngle;
						const outerX = centerX + radius * Math.cos(tickStart);
						const outerY = centerY + radius * Math.sin(tickStart);
						const innerX = centerX + (radius - 15) * Math.cos(tickStart);
						const innerY = centerY + (radius - 15) * Math.sin(tickStart);
						ctx.beginPath();
						ctx.moveTo(outerX, outerY);
						ctx.lineTo(innerX, innerY);
						ctx.setLineWidth(2);
						ctx.setStrokeStyle('#fff');
						ctx.stroke();
					}
				}
				this.sections.some((section, index) => {
					const sectionStart = startAngle + (totalAngle * currentScoreSum / this.maxScore);
					const sectionEnd = startAngle + (totalAngle * (currentScoreSum + section.range) / this
						.maxScore);
					if (this.currentScore >= currentScoreSum && this.currentScore < currentScoreSum + section
						.range) {
						ctx.beginPath();
						ctx.arc(centerX, centerY, radius, sectionStart, scoreAngle, false);
						ctx.lineWidth = 20;
						ctx.strokeStyle = section.color;
						ctx.stroke();
						// drawTick(section, sectionStart, sectionEnd)
						return true;
					} else if (this.currentScore >= currentScoreSum + section.range) {
						ctx.beginPath();
						ctx.arc(centerX, centerY, radius, sectionStart, sectionEnd, false);
						ctx.lineWidth = 20;
						ctx.strokeStyle = section.color;
						ctx.stroke();
					}
					if (index < this.sections.length - 1) {
						currentScoreSum += section.range + (gapAngle / totalAngle) * this.maxScore;
					} else {
						currentScoreSum += section.range;
					}
					//	drawTick(section, sectionStart, sectionEnd)
					return false;
				});
				if (this.currentSection) {
					ctx.setFontSize(12);
					ctx.setFillStyle("rgba(0,0,0,0.5)");
					ctx.setTextAlign('center');
					ctx.setTextBaseline('middle');
					ctx.fillText(this.currentSection.description, centerX, centerY + radius);
				}
				ctx.draw(false, (res) => {
					if (res.errMsg == "drawCanvas:ok") {
						if (this.elBgIdStart) {
							this.elBgIdStart = false;
							uni.canvasToTempFilePath({
								canvasId: 'gaugeCanvas',
								success: (res) => {
									this.elBgIdShowTwo = true;
									setTimeout(() => {
										this.elBgIdShowOne = false;
									}, 100);
									this.elBgIdUrl = res.tempFilePath;
								},
								fail: (err) => {
									console.error(err, 'err');
								}
							}, this);
						}
					}
				});
			},
			getPointerAngle() {
				const startAngle = Math.PI * 0.8
				const endAngle = Math.PI * 2.2
				const totalAngle = endAngle - startAngle
				return startAngle + (this.currentScore / this.maxScore) * totalAngle
			},
			getCurrentSection() {
				let cumulativeRange = 0;
				for (const section of this.sections) {
					cumulativeRange += section.range;
					if (this.currentScore <= cumulativeRange) {
						return section;
					}
				}
				return this.sections[this.sections.length - 1];
			},
			handleError(e) {
				console.error('Canvas error:', e)
			},
			updateScore(score) {
				this.currentScore = Math.max(0, Math.min(this.maxScore, Number(score)));
				this.currentSection = this.getCurrentSection();
				this.drawGauge();
			}
		}
	}
</script>

<style>
	.container {
		display: flex;
		justify-content: center;
		align-items: center;
		height: 300px;
		position: relative;
	}

	.gauge-canvas {
		width: 300px;
		height: 300px;
	}

	.center-area-box {
		position: absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
		width: 150px;
		/* 减小宽度 */
		height: 150px;
		/* 减小高度 */
		border-radius: 50%;
		z-index: 10;
		display: flex;
		justify-content: center;
		align-items: center;


	}

	.center-area {
		position: absolute;
		left: 0;
		top: 0;
		width: 150px;
		/* 减小宽度 */
		height: 150px;
		background: url(这里放带有指针的图片) no-repeat;
		background-size: 100% 100%;
		transform: rotate(-30deg);
		transition: .5s;
	}

	.center-text {
		position: relative;
		z-index: 11;
		font-weight: 600;
		font-size: 38rpx;
		color: rgba(0, 0, 0, 0.7);
		text-align: center;
		width: 76rpx;
		word-wrap: break-word;
	}
</style>